This Technical Note contains a collection of archived Q&A's relating to a specific topic--questions sent the Developer Support Center (DSC) along with answers from the DSC engineers. Current Q&A's can be found on the Macintosh Technical Q&A's web site.
Last reviewed: 6/24/93
Is it possible to abort an outstanding MacTCP name resolver call before it completes? The CloseResolver call description says that "[b]efore the application exits, the CloseResolver call must be made to release memory structures and terminate all outstanding domain name server calls." The very next sentence says that "CloseResolver must not be called until all outstanding resolver calls have been completed." Which of these statements is correct? If it's the latter one, then does that mean that if I make a StrToAddr call and it returns cache fault I have to wait for the result proc to be called before my application can quit? How long is that likely to be?
___
According to the MacTCP name resolver code, CloseResolver will abort any currently executing name lookup. In other words, you don't have to wait until your name resolver completion procedure gets called if you want abort the call.
Other things to be aware of are that you can't perform multiple name resolver lookups simultaneously, you can't call the name resolver from interrupt time, and the timeout for name resolver calls is hard-coded to 37 seconds before they'll complete with an error if no response is received. All of this information is valid as of MacTCP version 2.0.2 and prior releases as well.
On the Macintosh, I need to consistently listen on the same port for incoming connections. This behavior is analogous to the Listen and Accept functionality provided by the industry standard socket interface for TCP on UNIX systems. That is, I listen on a port/socket for incoming connections; when a remote system attempts to connect, a new socket is created representing that connection; and the port/socket performing the listen continues to listen for other connection requests.
When using the TCPPassiveOpen operation under MacTCP, the listen operation doesn't persist once an incoming connection is established. That is, the stream used to listen for an incoming request becomes the connection with the remote system. Once that connection is established, there's no stream listening for subsequent connection requests. Is there any way I can keep a listener active at all times? My application needs to have a listener constantly, or at least with as short a window of unavailability as possible.
___
You're right that with MacTCP's nonsocket interface there's no way to maintain a persistent listener using MacTCP. To emulate this functionality, you'll have to keep more than one listener active at all times. You can do this by queuing multiple TCPPassiveOpen commands asynchronously to the MacTCP driver. How many to queue depends on how fast you expect connections to come in and how quickly you can requeue new opens after connections are made. Three should probably be enough if you expect a relatively small number of connections and you can requeue new parameter blocks as you receive connections.
PBControl is safe to call at interrupt time in this case. Inside Macintosh X-Ref lists it as unsafe because it's impossible for them to know what kind of driver you might be calling. For a particular driver, calling it at interrupt time might be totally unsafe, totally safe, or safe to do asynchronously only. In the case of MacTCP, it falls under the "safe if asynchronous" category. Any asynchronous calls to it will queue up and wait, so it's safe to post them from an interrupt or an ASR. However, since there isn't an ASR event for Notify, I agree that using an ASR isn't a solution for you in this case.
There is some sample code you might find useful. On the Developer CD, under the path ":Technical Documentation:Sample Code:Snippets:Networking:TCP Server:" you'll find a sample server that uses TCP.
When I dial into my AppleTalk network none of my MacTCP-based software works. I have MacTCP configured with an IP number on the remote machine, and Telnet (a MacTCP-based application) runs fine, but I can't connect to any of the hosts on the network I'm dialed into. What could be causing this problem?
___
The problem may be because you don't have a device on the dial-in net to act as a proxy IP Encapsulation service. When you select the AppleTalk icon (such as LocalTalk, EtherTalk, or Dial-In) in the MacTCP control panel, you're using a MDEV (IP Link layer) that encapsulates the IP data into an AppleTalk packet and sends it out. You therefore need to have something on the other side that will break out the IP data from the AppleTalk packet and send it out as an IP frame on the network you're dialed into.
There are several third-party solutions to this problem, the Shiva FastPath and Cayman Gator Boxes being the most common. The feature is normally called IP Encapsulation or KIP. If you use MacTCP this way, you must select the zone via the pop-up menu in the MacTCP control panel that the IP Encapsulation device is in. You must also configure the IP Encapsulation device to give out IP numbers, and set the remote Macintosh to "Server" IP addressing in the MacTCP control panel.
Note: Two Macintosh systems using IP Encapsulation should be able to communicate peer to peer, but they won't be able to contact non-IP Encapsulation devices.
Definition: IP Encapsulation: The act of taking IP data frames (packets) and placing them inside an AppleTalk packet for transport over an AppleTalk-only media (also known as LocalTalk and ARA). Also known as KIP or KSTAR, which are both names left over from the Kinetics FastPath.
Last reviewed: 6/14/93
Is it possible to increase ARP cache size? It appears that MacTCP has memory to cache 35 to 40 entries. If my application sends out IP requests periodically to about 40 unique IP stations, MacTCP drops some entries, and makes an ARP request. Is there any way to program the cache size to a higher limit?
___
Unfortunately, the number of ARP table entries is hard-coded to 20 in the MacTCP source code, and the ARP time-out for aging entries out of the ARP cache is also hard-coded to 10 minutes. There's no way to change these values, since they are in the code as #defines and used throughout.
Last reviewed: 8/1/92
How do I cancel transactions (specifically connect requests) under MacTCP? I know that I can specify a timeout; however, I would like the user to be able to hit `Command-.' if the transaction's tired of waiting. I tried KillIO but that seems to crash.
___
Since MacTCP uses the Control call instead of reads and writes, the killio call is not supported to abort a transaction. You should use Abort and Release. Abort terminates the connection and Release releases the stream. As an alternative, a TCPPassiveOpen could be cancelled by issuing an active open from the same machine on the listening port.
Last reviewed: 8/1/92
We need the following to port our mainframe front-end application to the Macintosh:
* a C++ compiler compatible with AT&T 2.0 (and ANSI C)
* a TCP/IP library with an Application Programming Interface (API) similar to sockets
* an Ethernet card
___
MPW C++ is based on AT&T CFront 2.0. For information about CFront 2.0, please refer to the UNIX System V AT&T C++ Language System Release 2.0 Product Reference Manual.
Sockets is the general UNIX (Berkeley) API for TCP/IP programming. Apple currently offers some libraries that allow you to work with MacTCP but not APIs similar to sockets. Third-party socket libraries for MacTCP are available, however. Also, universities such as the University of Toronto provide public domain socket wrappers for MacTCP.
Ethernet cards are available from a number of sources, including Apple's Ethernet cards.
Last reviewed: 6/14/93
What are the MacTCP Subnet Mask and Gateway Address fields used for?
___
In the TCP/IP protocol, there are a couple of provisions for simplifying the addressing scheme for smaller local networks. One of these is the subnet mask. It allows the sender to identify the destination machine by a shorter address, which is long enough to distinguish all the machines on the local network. This mask is made up of four octets, and is used as a bitwise mask to show how many bits are being used to specify the network number, subnet number, and node. The gateway address field specifies the IP address of the local network's router. Packets destined for another network are sent to this router, which then transmits the packets to other networks.
Last reviewed: 8/1/92
Is it possible to have both the source and the destination application on the same machine if they are using MacTCP to communicate? If so, what should I do to make sure both applications share the processor so this works properly?
___
It is possible to use MacTCP to communicate to different processes on the same Macintosh computer. Unlike PPC, MacTCP does not bypass the network for same-machine connections, so there is still some "network traffic" involved.
As far as "sharing" the processor goes, this is very important in what you are doing. Here's a brief outline of what you need to do:
* Make asynchronous MacTCP driver calls;
* If you want to use polled I/O, you can wait for ioResult < 1 to tell when the call completes. Otherwise, you may want to have a completion routine which queues completed calls for processing at event time; or
* Call WaitNextEvent or EventAvail while waiting for driver calls to complete (this gives time to the other MacTCP applications).
For a good reference on using "idle procs" to give time to background applications when using MacTCP, refer to the article, "MacTCP Cookbook" in develop, Issue 6 and get the "NewsWatcher" source code from the Developer CD Series.
Last reviewed: 6/14/93
Using StrToAddr, you can receive up to four IP network addresses returned by the service for the host requested, but the MacTCP Programmer's Guide does not say how to tell how many of the addresses are valid. According to the name resolver code, MacTCP zeros out 4 long words before the StrToAddr lookup and then fills in the addresses it finds. This means that the array contains at most 4 addresses, and is terminated by a zero address (0.0.0.0) if fewer than four addresses are returned.
Last reviewed: 6/14/93
Is the MacTCP resolver code contained in the domain name resolver (DNR)?
___
The resolver code is contained in the MacTCP DNR, as well as in the MacTCP control panel. The DNR code is stored as a resource file in the System folder and is read into memory as necessary in order to convert host names into addresses. It is used in conjunction with a domain name server or with the local hosts file.
Last reviewed: 6/14/93
Where should the MacTCP Hosts file be located, and who looks for that file?
___
According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), the Hosts file should be located in the user's System Folder. The file maps machine names to internet addresses, providing the same service as the domain name server. The Hosts file can be used if you have no domain server on your network. It is also suggested that this file be used for frequently used name-to-address mappings. Instructions on setting up the file are included in the MacTCP documentation.
Last reviewed: 6/14/93
Under MacTCP, what is the significance of the "obtain address" options, with
respect to (1) manually, (2) server, and (3) dynamically?
___
According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), "obtain address" means the following:
* Manually: You will need to fill in some or all of the fields in the IP Address box;
* Server: The Internet Protocol (IP) address for the user Macintosh is automatically obtained from a server every time the user Macintosh boots up. This option requires
- a Reverse Address Resolution Protocol (RARP) or Bootstrap Protocol (BootP) server on an Ethernet, or
- a Datagram Delivery Protocol-to-Internet Protocol (DDP-IP) gateway on an AppleTalk network that's compatible with the Kinetics Internet Protocol (KIP) developed at Stanford (also called "IPTalk"), such as the Shiva Fastpath or Cayman Gatorbox
* Dynamically: The node portion of the IP address for the user Macintosh is set dynamically every time the user Macintosh boots up. With this option you still need to set some of the fields in the IP Address Box. All these processes are described in further detail in the MacTCP documentation.
Last reviewed: 6/14/93
Does MacTCP actually support SLIP? If not, does Apple plan to provide SLIP support in the future. Does anyone know of any company that does a SLIP for the Macintosh?
___
SLIP is an asynchronous, serial line protocol developed for running TCP/IP over serial communications lines in a point-to-point configuration. SLIP was developed to transmit IP packets over low-speed, sometimes noisy, asynchronous communications lines where error recovery and an efficient line protocol are needed. The SLIP protocol is now being replaced with a new serial line protocol named "PPP," which uses a more efficient means of establishing a point-to-point IP connection.
MacTCP includes hooks that let you write different link-layer modules. This makes possible the development of interfaces to SLIP, PPP, and to any other link layer that someone may need, like broadband, X.25, and FDDI. Apple does not currently provide support in MacTCP for SLIP or any other serial line protocol. There are, however, several third-party SLIP extensions available for use with MacTCP.
Last reviewed: 6/14/93
I'm using MacTCP v1.1 with Think C, and when calling StrToAddr with hostname = "90.25.3.240", the returned addr field has the following:
addr [0] = 0X00005A19 addr [1] = 0X03F00000
The correct answer should be addr [0] = 0X5A1903F0. What's the problem?
___
The StrToAddr problem you are experiencing is related to a shortcoming in the header files. The structure for the hostInfo record you are accessing (from AddressXlation.h)is as follows:
typedef struct hostInfo { int rtnCode; char cname[255]; unsigned long addr[NUM_ALT_ADDRS]; };
The problem with the way the structure is defined is that rtnCode is defined as an "int." The size of an int is dependent on your development environment. In MPW, ints are 4 bytes, while Think C uses 2 byte ints as its default. If you're using Think C, you will see the addresses shifted forward in the storage by 2 bytes, since the rtnCode structure causes the rest of the struct to be shifted forward in memory.
If you're using Think C 5.0 or later, you can either check the "Use 4 byte ints" check-box in the preferences, or you can change the header files to use "long" in place of "int" (a Think C long is the same size as an MPW int). A set of header diffs for Think C compatibility with MacTCP is on the latest Apple Developer CD Series disc in Tools & Apps: Networking &Communication: MacTCP 1.1 DTS Header Changes.
Last reviewed: 6/14/93
Does MacTCP's EnumCache name resolver call return the data in a particular order or randomly?
___
Since the EnumCache documentation doesn't specify any particular sequence for name resolver cache enumeration, it's best to play it safe and not assume any particular order for the data returned by the call. Since the internals of the name resolver may change in the future, you probably don't want to rely on any undocumented data ordering assumptions. If you want the entries separated, the best way probably would be to have a dynamically-sized array for each of the entry types (such as addresses, HInfo, and name servers) and fill them in the EnumCache callback.
Last reviewed: 6/14/93
When I attempt to connect to a LocalTalk net using MacTCP 1.1, after opening the MacTCP driver, this error occurs: "Error opening driver / Error in getting address (-23004)". I'm running System 7.0 on a Macintosh IIci with Shiva Fastpath 4.0, and I've configured TCP Admin as follows:
Indicate Resident Zone
Click More
Dynamic addressing
Range 1 to 65534
Enter Gateway Address (address of Fastpath for resident zone)
Enter Domain Name & Address
___
The Fastpath won't work with MacTCP configured to use dynamic addressing. You need to set MacTCP to use server-based addressing. If you change this setting, and the FastPath is configured correctly, you should be up and running.
Last reviewed: 6/14/93
MacTCP 1.1 packets containing "urgent data" have the so-called "urgent pointer" set according to RFC 1122. All our TCP/IP hosts expect a behavior corresponding to RFC 793, however. Is there a possibility to configure MacTCP to this effect?
___
MacTCP can send urgent data according to either RFC 1122 or RFC 793; however, it is not a setting in the driver that determines this. When a programmer makes the TCPSend call, he sets a flag in his parameter block that indicates whether or not to use urgent data, and which version of urgent data to use. Therefore, you would have to modify the program that you are using to set up the parameter blocks appropriately.
To send urgent data using the non-compliant RFC 793 method, set the urgent flag in the TCPSend parameter block to 2. Any other nonzero value in the urgent flag indicates the RFC 1122 method should be used.
Last reviewed: 6/14/93
I'm trying to use the ICMP echo request function described on page 88 of the MacTCP Developer's Kit 1.1 manual to 'ping' a TCP host before trying to open a connection. The problems I'm having seem centered around the ICMPEchoNotifyProc. If I declare the proc as
pascal void MyEchoNotifyProc (struct ICMPParamBlock *iopb)
the proc gets called and the ICMPParamBlockPtr is valid. But after the proc returns, my Macintosh crashes. Can you give me any suggestions as to how to make this puppy work?
___
You've found a "bug" in the manual. The ICMPEchoNotifyProc is actually defined as:
typedef void (*ICMPEchoNotifyProc) (struct ICMPParamBlock *iopb);
The definition is correct in <MiscIPPB.h>. Note that in this definition, the proc uses C, not Pascal calling conventions. In C, the caller removes the parameters from the stack, not the callee, so since your routine has already removed the parameters before returning, they are removed twice, corrupting the stack. Changing your procedure to use C calling conventions should fix your problem.
Last reviewed: 8/1/92
We have implemented a TCP/IP product using MacTCP Development Kit version 1.1. If MacTCP version 1.0.1 is installed, will there be any compatibility problems with our implementation.?
___
There are only a very few new calls in MacTCP 1.1 that aren't in the 1.0.1 driver. Among these are:
* Name resolver HInfo and MXInfo calls
* UDP multi-port sends and receives
* ICMP echo protocol support
As long as you're not using any of these features, any program developed for MacTCP 1.1 will work with 1.0.1.
Last reviewed: 8/1/92
MacTCP 1.1, Apple's System 7-compatible version of MacTCP, fixes several problems in earlier releases, but doesn't address several header file incompatibilities. This short note outlines the MacTCP 1.1 header file problems, but it does not include the fixes. Patches in the form of MPW "compare" output are available on Apple's latest Developer CD Series disc. The new headers are available as part of the "MacTCP Developers' Kit," available from APDA (part #M0704/C).
Each header problem is described below, organized by file(s) containing the problem and classified as a general bug or shortcoming, a Think C incompatibility, or a C++ incompatibility. NOTE: The changes have not been thoroughly tested, so use them cautiously.
Problems affecting all header files:
* General problem: Each header file is missing the
#ifdef __cplusplus extern "C" { #endif
and
#ifdef __cplusplus extern "C" { #endif
which are necessary for C++ unmangling.
* General problem: There are no #ifdefs to prevent including a file multiple times, as in other Apple headers. This was fixed by adding the following to each of the header files:
#ifndef __MACTCPCOMMONTYPES__ #define __MACTCPCOMMONTYPES__ ... #endif
where "MACTCPCOMMONTYPES" is replaced by the name of the header file.
* Think C problem: Think C before 5.0 does not support pascal typedefs, which MacTCP makes use of, so #ifdef THINK_C was added in several instances to declare these pascal typedef functions as type ProcPtr. This fixes the problem.
GetMyIPAddr.h problem:
* General problem: ParamBlockHeader is used as a #define here, conflicting with its use in <Files.h>. The solution is to change the name of the #define to IPParamBlockHeader.
MiscIPPB.h problems:
* General problem: ParamBlockHeader is used as a #define here, conflicting with its use in <Files.h>. The solution is to change the name of the #define to GetIPParamBlockHeader.
* General problem: The structure IPParamBlock is defined in this file with a different definition from the one in GetMyIPAddr.h. The solution is to change the name of the struct.
* General problem: AppleTalk.h is required for successful compilation. Code was added to include this if it has not already been included.
* General problem: icmpEchoTimeoutErr is defined in MacTCPCommonTypes in addition to being defined in MiscIPPB.h. Solution is to remove its definition here.
AddressXLation.h problems:
Think C incompatibility: The "int" type is used within the "hostInfo" structure definition. The default size of an int is different from Think to MPW. In all cases, int in the MacTCP headers should be changed to long.
* Think C incompatibility: The returnRec struct uses an int. Fix is to change to a long as above.
* Think C incompatibility: The CloseResolver() prototype is defined with an empty parameter list, not with a void parameter list. Think C requires the void to consider the definition a prototype. The fix is to add the void keyword as the function parameter list.
* C++ incompatibility: The cacheEntryRecord struct uses a variable named "class". This causes major problems with C++ compilers, since the class keyword takes on a different meaning in this instance. The fix is to change this to "cacheClass."
dnr.c problems:
* General/Think C problem: The typedef for OSErrProcPtr was incomplete, causing ambiguity for argument casting. This was changed to "typedef OSErr (*OSErrProcPtr)(long,...);" to make sure the first parameter to the name resolver calls is passed as a long.
* Think C incompatibility: Defines in Think default to short, not long, so all name resolver calls are made incorrectly. This is fixed by the typedef in above, but Think 4.0.5 does not recognize partial prototypes correctly. The fix is to add a "L" to the end of each of the name resolver command #defines.
* Think C incompatibility: The MXInfo() procedure has an extra semicolon after the trailing brace "};" which causes a syntax error with the Think C compiler. The semicolon was removed to fix the problem.
Last reviewed: 6/14/93
I want to access MacTCP in a Pascal program. Do you have the C parameter block definitions available as Pascal records or will I have to do my own translation?
___
Unfortunately, Pascal header files and interfaces are not available for MacTCP. If you want to use Pascal, you'll have to translate the interfaces.
One problem you will run into is that all MacTCP routines and callbacks (those in dnr.c/dnr.o, for example) use C calling conventions. You'll still be able to call the dnr routines by declaring them as external C functions, as described in the MPW Pascal documentation, but you'll still have to write any callback functions in C or Assembler, since the Pascal compiler can only call a function using C conventions, but you can't declare a Pascal function to have C conventions.
X-Ref:
MacTCP Programmer's Guide, Chapter 4, page 47
Last reviewed: 7/13/92
Are MacTCP's Type Of Service (Reliability, Low Delay and Thruput) bit settings swapped in the documentation?
___
The bit settings in the MacTCP programmer's documentation are reversed for the Type of Service constants. This will be fixed in a future version of the manual. The bit settings should be as follows:
Type of Service Byte (3-bit field)
Bit 0 set for low delay
Bit 1 set for high reliability
Bit 2 set for high throughput
If you wish to correct these settings they can be found on page 35 of the MacTCP Programmer's Guide.
Last reviewed: 7/13/92
In the MacTCP Developer's Kit (Version 1.1) there is a ULP timeout action field which is used in several PowerBook calls to MacTCP. For some calls, zero indicates an abort and nonzero indicates a report. TCPSend, TCPClose and TCPStatus are this way. For other calls, the reverse is documented (0 indictes report and 1 indicates abort). TCPActiveOpen and TCPPassiveOpen are this way. Can I believe the documentation or are there errors in it ? If there are errors, what is the correct way it should be ?
___
According to the MacTCP source code, and you're right, the documentation is incorrect. For each of the calls with a ULP timeout action, the correct values are:
1 = abort
0 = report only
Last reviewed: 9/15/92
My application uses the Macintosh Communications Toolbox and ADSP to connect to network services. What software do I need to get to make the same connections using TCP/IP? MacTCP or other recommendations?
___
Apple only makes one MacTCP Communications Toolbox tool that works specifically with MacX and TCP/IP (the TCP Tool). This tool is not supported for use by third party developers. For CTB/MacTCP connection tools which are supported, you need to get a third-party CTB MacTCP tool. These are available from several vendors. For example, TCPack from ASC (Advanced Software Concepts) is a set of Connection Tools designed to allow simultaneous TCP/IP connections using Apple's MacTCP driver. All Apple's terminal tools (asc3270, asc5250, ...), the Apple standard terminal tools (TTY, VT100, VT320), as well as several third-party terminal tools can be used to enter terminal sessions with TCPack. TCP/Tools from InterCon Systems is another package which allows you to use existing CTB applications to log onto Unix workstations using your LocalTalk or EtherTalk network.